﻿using System;
using Sustainalytics.Entities;
using System.Security.Claims;
using System.Collections.Generic;
using Xunit;

namespace Sustainalytics.Claims.BL.Tests
{
    [Trait("Category", "Unit")]
    public class ClaimMapComparerTest
    {
        [Fact]
        public void DiffInvaliInput1Test()
        {
            TestInvalidParams(null, new ClaimMap() { Permission = "Permission2", Claims = new List<Claim>() });
        }

        [Fact]
        public void DiffInvaliInput2Test()
        {
            TestInvalidParams(new ClaimMap() { Permission = "Permission2", Claims = new List<Claim>() }, null);
        }

        private static void TestInvalidParams(ClaimMap leftClaimMap, ClaimMap rightClaimMap)
        {
            bool accountDif;
            List<Claim> leftAdds;
            List<Claim> rightAdds;
            var claimMapComparer = new ClaimMapComparer();

            Assert.Throws<ArgumentException>(() => { claimMapComparer.Diff(leftClaimMap, rightClaimMap, out accountDif, out leftAdds, out rightAdds); });
        }

        [Fact]
        public void Diff2DifferentClaimMapTest()
        {
            var claimMapComparer = new ClaimMapComparer();

            var leftClaimMap = new ClaimMap() { Permission = "Permission1", Claims = new List<Claim>() };
            var rightClaimMap = new ClaimMap() { Permission = "Permission2", Claims = new List<Claim>() };
            bool permissionDif;
            List<Claim> leftAdds;
            List<Claim> rightAdds;

            var result = claimMapComparer.Diff(leftClaimMap, rightClaimMap, out permissionDif, out leftAdds, out rightAdds);

            Assert.Equal(true, result);
            Assert.Equal(true, permissionDif);
        }

        [Fact]
        public void Diff1AdditionalClaimForEachTest()
        {
            var issuer = "Sustainalytics";
            var claimMapComparer = new ClaimMapComparer();

            var claimLeft = new Claim("Home", "Allow.All", ClaimValueTypes.String, issuer);
            var leftClaimMap = new ClaimMap()
            {
                Permission = "Permission1",
                Claims = new List<Claim>() {
                    new Claim("Screening Tool", "Allow.Read", ClaimValueTypes.String, issuer),
                    new Claim("Dashboard", "Allow.Read", ClaimValueTypes.String, issuer),
                    claimLeft,
                }
            };

            var claimRight = new Claim("Porfolio", "Allow.Read", ClaimValueTypes.String, issuer);
            var rightClaimMap = new ClaimMap()
            {
                Permission = "Permission1",
                Claims = new List<Claim>() {
                    new Claim("Screening Tool", "Allow.Read", ClaimValueTypes.String, issuer),
                    new Claim("Dashboard", "Allow.Read", ClaimValueTypes.String, issuer),
                    claimRight
                }
            };

            bool permissionDif;
            List<Claim> leftAdds;
            List<Claim> rightAdds;

            var result = claimMapComparer.Diff(leftClaimMap, rightClaimMap, out permissionDif, out leftAdds, out rightAdds);

            Assert.Equal(true, result);
            Assert.Equal(false, permissionDif);

            Assert.Equal(1, leftAdds.Count);
            Assert.Equal(1, rightAdds.Count);

            Assert.Equal(leftAdds[0], claimLeft);
            Assert.Equal(rightAdds[0], claimRight);
        }
        [Fact]
        public void Diff1ChangedClaimForEachTest()
        {
            var issuer = "Sustainalytics";
            var claimsMapComparer = new ClaimMapComparer();

            var claimLeft = new Claim("Home", "Allow.All", ClaimValueTypes.String, issuer);
            var leftClaimMap = new ClaimMap()
            {
                Permission = "Permission1",
                Claims = new List<Claim>() {
                    new Claim("Screening Tool", "Allow.Read", ClaimValueTypes.String, issuer),
                    new Claim("Dashboard", "Allow.Read", ClaimValueTypes.String, issuer),
                    claimLeft,
                }
            };

            var claimRight = new Claim("Home", "Allow.Read", ClaimValueTypes.String, issuer);
            var rightClaimMap = new ClaimMap()
            {
                Permission = "Permission1",
                Claims = new List<Claim>() {
                    new Claim("Screening Tool", "Allow.Read", ClaimValueTypes.String, issuer),
                    new Claim("Dashboard", "Allow.Read", ClaimValueTypes.String, issuer),
                    claimRight
                }
            };

            bool permissionDif;
            List<Claim> leftAdds;
            List<Claim> rightAdds;

            var result = claimsMapComparer.Diff(leftClaimMap, rightClaimMap, out permissionDif, out leftAdds, out rightAdds);

            Assert.Equal(true, result);
            Assert.Equal(false, permissionDif);

            Assert.Equal(1, leftAdds.Count);
            Assert.Equal(1, rightAdds.Count);

            Assert.Equal(leftAdds[0], claimLeft);
            Assert.Equal(rightAdds[0], claimRight);
        }

        [Fact]
        public void DiffIdenticalClaimsTest()
        {
            var issuer = "Sustainalytics";
            var claimMapComparer = new ClaimMapComparer();

            var leftClaimMap = new ClaimMap()
            {
                Permission = "Permission1",
                Claims = new List<Claim>() {
                    new Claim("Screening Tool", "Allow.Read", ClaimValueTypes.String, issuer),
                    new Claim("Dashboard", "Allow.Read", ClaimValueTypes.String, issuer),
                    new Claim("Home", "Allow.Read", ClaimValueTypes.String, issuer)
                }
            };

            var rightClaimMap = new ClaimMap()
            {
                Permission = "Permission1",
                Claims = new List<Claim>() {
                    new Claim("Screening Tool", "Allow.Read", ClaimValueTypes.String, issuer),
                    new Claim("Dashboard", "Allow.Read", ClaimValueTypes.String, issuer),
                    new Claim("Home", "Allow.Read", ClaimValueTypes.String, issuer)
                }
            };

            bool permissionDif;
            List<Claim> leftAdds;
            List<Claim> rightAdds;

            var result = claimMapComparer.Diff(leftClaimMap, rightClaimMap, out permissionDif, out leftAdds, out rightAdds);

            Assert.Equal(false, result);
        }
    }
}
